<template>
  <div class="map">
    <div class="map-container">
      <div class="map-container-title">xxx标题</div>
      <div class="map-chart" id="mapEchart"></div>
    </div>
  </div>
</template>

<script>
import mixins from "./mixins.js";
import { getMap } from "./maputils.js";
import geoJson from "./china.json";
import axios from "axios";

export default {
  mixins: [mixins],
  props: {
    cityMapName: {
      type: String,
      require: false,
      default: "中国",
    },
    mapData: {
      type: Array,
      require: false,
      default: () => [],
    }
  },
  data() {
    return {
      citylist: [{ 中国: "401200965" }],
      lastCity: {},
      mapName: "china",
      mode: "2",
      myChart: {},
      geoName: "china",
      // mapData: [],
      isCity: true,
      plotData1: [],
      plotData2: [],
    };
  },
  watch: {
    // 监听父组件中的数据变化
    echartsData: {
      deep: true,
      handler(val) {
        this.initCharts(val);
      },
    },
    // 监听省份变化
    province: {
      deep: true,
      handler(val) {
        this.mapActive(val);
      },
    },
  },
  mounted() {
    // this.getMapJSON();
    this.chartMap();
  },
  beforeDestroy() {
    // 防止内存泄露
    if (!this.myChart) {
      return;
    }
    this.myChart.dispose();
    this.myChart = null;
  },
  methods: {
    chartMap() {
      let geoName = "china"
      console.log(1111, this.mapData)
      // 图表配置项
      const option = {
        tooltip: {
          show: true, // 提示框
          trigger: "item",
          backgroundColor: "rgba(255, 255, 255, 0)",
          borderWidth: 0,
          padding: 0,
          renderMode: "html",
          appendToBody: "true",
          className: "custom-tooltip-box",
          formatter: function (params) {
            let keys = Object.keys(params.data.name);
            let html;
            if (params.seriesType === "map3D" && keys.includes("orgNum")) {
              // 可在JS文件单独引入CSS文件(import 'xx.css';)，这里把CSS文件里定义的样式复制到style
              html = `<div class="custom-tooltip-box"  style="width: 263px;height: 170px;font-size: 18px;padding: 28px 20px;box-sizing: border-box;background-image: url('/modal-bk.png');background-size: 100% 100%;">`;
              html += `<div class="title" style="font-size: 25px;color:#29F1FAFF;line-height: 25px;font-size: 18px;">${params.name}</div>`;
              html += `<div class="row" style="margin-top: 10px;">`;
              html += `<span class="label" style="font-size: 18px;color: #fff;margin-right: 6px;">社区服务中心：</span>`;
              html += `<span style="color: #fff; font-size: 18px;" class="content">${params.value.communityNum}</span>`;
              html += `</div>`;
              html += `<div class="row" style="margin-top: 10px;">`;
              html += `<span class="label" style="font-size: 18px;color: #fff;margin-right: 6px;">养老服务机构：</span>`;
              html += `<span style="color: #fff; font-size: 18px;" class="content">${params.value.orgNum}</span>`;
              html += `</div>`;
              html += `<div class="row" style="margin-top: 10px;">`;
              html += `<span class="label" style="font-size: 18px;color: #fff;margin-right: 6px;">住宅小区：</span>`;
              html += `<span style="color: #fff; font-size: 18px;" class="content">${params.value.residenceNum}</span>`;
              html += `</div>`;
              html += `</div>`;
            } else if (params.seriesType === "scatter3D") {
              html += `<div class="title" style="font-size: 25px;color:#fff; line-height: 25px;font-size: 18px;">${params.name}</div>`;
            } else {
              html = "";
            }
            return html;
          },
        },
        geo3D: {
          zlevel: -10,
          map: geoName, // 地图类型。echarts-gl 中使用的地图类型同 geo 组件相同
          // data: this.mapData, //这里比较重要：获得过滤后的data，这样点击事件时就能获得这个data的值
          regionHeight: 5, //地图高度
          // top:60,
          // left:-30,
          // 地图表面纹理贴图
          // shading: "realistic",
          // realisticMaterial: {
          //   detailTexture: require("./bg4.jpg"),
          // },
          itemStyle: {
            borderWidth: 1,
            borderColor: "#2768BE", //地图边界颜色
            color: "#1970c3",
            opacity: 1,
          },
          label: {
            show: geoName !== "china" ? false : true, // 是否显示标签（地图区域名称）。
            color: "#fff",
            fontSize: 14,
            formatter: (e) => {
              return ` ${e.name} `;
            },
          },
          emphasis: {
            label: {
              show: true,
              color: "#fff",
            },
            itemStyle: {
              // color: "transparent",
              color: "#043f93",
            },
          },
          light: {
            // 光照相关的设置。在 shading 为 'color' 的时候无效。  光照的设置会影响到组件以及组件所在坐标系上的所有图表。合理的光照设置能够让整个场景的明暗变得更丰富，更有层次。
            main: {
              // 场景主光源的设置，在 globe 组件中就是太阳光。
              color: "#33fefe", //地图边缘颜色
              intensity: 120, //主光源的强度。[ default: 1 ]
              shadow: true, //主光源是否投射阴影。默认关闭。    开启阴影可以给场景带来更真实和有层次的光照效果。但是同时也会增加程序的运行开销。
              shadowQuality: "high", // 阴影的质量。可选'low', 'medium', 'high', 'ultra' [ default: 'medium' ]
              alpha: 0, // 主光源绕 x 轴，即上下旋转的角度。配合 beta 控制光源的方向。[ default: 40 ]
              beta: 0, // 主光源绕 y 轴，即左右旋转的角度。[ default: 40 ]
            },
            ambient: {
              // 全局的环境光设置。
              color: "#fff", // 环境光的颜色。[ default: #fff ]
              intensity: 1, // 环境光的强度。[ default: 0.2 ]
            },
          },
          postEffect: {
            bloom: {
              enable: true,
              bloomIntensity: 1,
            },
          },
          viewControl: {
            //   // 用于鼠标的旋转，缩放等视角控制。
            //   projection: 'perspective', // 投影方式，默认为透视投影'perspective'，也支持设置为正交投影'orthographic'。
            //   autoRotate: false, // 是否开启视角绕物体的自动旋转查看。[ default: false ]
            //   autoRotateDirection: 'cw', // 物体自传的方向。默认是 'cw' 也就是从上往下看是顺时针方向，也可以取 'ccw'，既从上往下看为逆时针方向。
            //   autoRotateSpeed: 10, // 物体自传的速度。单位为角度 / 秒，默认为10 ，也就是36秒转一圈。
            //   autoRotateAfterStill: 3, // 在鼠标静止操作后恢复自动旋转的时间间隔。在开启 autoRotate 后有效。[ default: 3 ]
            //   damping: 0, // 鼠标进行旋转，缩放等操作时的迟滞因子，在大于等于 1 的时候鼠标在停止操作后，视角仍会因为一定的惯性继续运动（旋转和缩放）。[ default: 0.8 ]
            //   rotateSensitivity: 1, // 旋转操作的灵敏度，值越大越灵敏。支持使用数组分别设置横向和纵向的旋转灵敏度。默认为1, 设置为0后无法旋转。	rotateSensitivity: [1, 0]——只能横旋转； rotateSensitivity: [0, 1]——只能纵向旋转。
            //   zoomSensitivity: 1, // 缩放操作的灵敏度，值越大越灵敏。默认为1,设置为0后无法缩放。
            //   panSensitivity: 1, // 平移操作的灵敏度，值越大越灵敏。默认为1,设置为0后无法平移。支持使用数组分别设置横向和纵向的平移灵敏度
            //   panMouseButton: 'left', // 平移操作使用的鼠标按键，支持：'left' 鼠标左键（默认）;'middle' 鼠标中键 ;'right' 鼠标右键(注意：如果设置为鼠标右键则会阻止默认的右键单。)
            //   rotateMouseButton: 'left', // 旋转操作使用的鼠标按键，支持：'left' 鼠标左键;'middle' 鼠标中键（默认）;'right' 鼠标右键(注意：如果设置为鼠标右键则会阻止默认的右键单。)
            distance: this.isCity ? 220 : 120, // [ default: 100 ] 默认视角距离主体的距离，对于 grid3D 和 geo3D 等其它组件来说是距离中心原点的距离,对于 globe 来说是距离地球表面的距离。在projection 为'perspective'的时候有效。
            minDistance: 60, // [ default: 40 ] 视角通过鼠标控制能拉近到主体的最小距离。在 projection 为'perspective'的时候有效。
            maxDistance: 280, // [ default: 400 ] 视角通过鼠标控制能拉远到主体的最大距离。在 projection 为'perspective'的时候有效。
            alpha: 90, // 视角绕 x 轴，即上下旋转的角度。配合 beta 可以控制视角的方向。[ default: 40 ]
            beta: 10, // 视角绕 y 轴，即左右旋转的角度。[ default: 0 ]
            // //   minAlpha: 25, // 上下旋转的最小 alpha 值。即视角能旋转到达最上面的角度。[ default: 5 ]
            // //   maxAlpha: 360, // 上下旋转的最大 alpha 值。即视角能旋转到达最下面的角度。[ default: 90 ]
            // //   minBeta: -360, // 左右旋转的最小 beta 值。即视角能旋转到达最左的角度。[ default: -80 ]
            // //   maxBeta: 360, // 左右旋转的最大 beta 值。即视角能旋转到达最右的角度。[ default: 80 ]
            // center: [-30, 60, 0], // 视角中心点，旋转也会围绕这个中心点旋转，默认为[0,0,0]。
            //   animation: true, // 是否开启动画。[ default: true ]
            //   animationDurationUpdate: 1000, // 过渡动画的时长。[ default: 1000 ]
            //   animationEasingUpdate: 'cubicInOut', // 过渡动画的缓动效果。[ default: cubicInOut ]
          },
          // itemStyle: {
          //   color: "transparent",
          //   shadowColor: 'rgba(22, 255, 255, 0.5)',
          //   shadowOffsetX:10,
          //   shadowOffsetY:10,
          //   shadowBlur: 10,
          // },
        },
        graphic: { // 左上角操作按钮
          type: "text",
          x: 25,
          y: 25,
          style: {
            text: "返回",
            fill: "#333",
            font: 'bolder 1em "Microsoft YaHei", sans-serif'
          },
          onclick: () => {
            // 利用函数的作用域，可以直接拿上面的name来用
            if (this.citylist.length < 2) return;
            this.lastCity = this.citylist[this.citylist.length - 2];
            const name = Object.keys(this.lastCity)[0];
            const [grahpName, graphJson] = getMap(name);
            // 删除最后一个元素
            this.citylist.pop();
            // 很多操作重复了，可以将公共部分抽离出来
            option.geo3D.map = grahpName;
            option.series.map = mapName;

            this.$echarts.registerMap(grahpName, graphJson);
            this.myChart.setOption(option, true);
          },
        },
        series: [
          {
            zlevel: -9,
            map: geoName, // 地图类型。echarts-gl 中使用的地图类型同 geo 组件相同
            type: "map3D",
            data: this.mapData,
            // regionHeight: 5,//地图高度
            // top:60,
            // left:-30,
            itemStyle: {
              color: "#1970c3",
              // borderWidth: 3,
              // borderColor: "#33fefe",//地图边界颜色
              // borderColor: "red",//地图边界颜色
              // opacity: 1,
              // shadowColor: 'rgba(22, 255, 255, 0.5)',
              // shadowOffsetX:10,
              // shadowOffsetY:10,
              // shadowBlur: 10,
            },
            emphasis: {
              label: {
                show: false,
                color: "#fff",
              },
              itemStyle: {
                color: "#1b8cd5",
              },
            },
            label: {
              show: true, // 是否显示标签（地图区域名称）。
              color: "#fff",
              fontSize: 14,
              formatter: (e) => {
                return ` ${e.name} `;
              },
            },
            // 地图表面纹理贴图
            // shading: "realistic",
            // realisticMaterial: {
            //   detailTexture: require("./bg4.jpg"),
            // },
            light: {
              // 光照相关的设置。在 shading 为 'color' 的时候无效。  光照的设置会影响到组件以及组件所在坐标系上的所有图表。合理的光照设置能够让整个场景的明暗变得更丰富，更有层次。
              main: {
                // 场景主光源的设置，在 globe 组件中就是太阳光。
                color: "#33fefe", //地图边缘颜色
                intensity: 120, //主光源的强度。[ default: 1 ]
                shadow: true, //主光源是否投射阴影。默认关闭。    开启阴影可以给场景带来更真实和有层次的光照效果。但是同时也会增加程序的运行开销。
                shadowQuality: "high", // 阴影的质量。可选'low', 'medium', 'high', 'ultra' [ default: 'medium' ]
                alpha: 0, // 主光源绕 x 轴，即上下旋转的角度。配合 beta 控制光源的方向。[ default: 40 ]
                beta: 0, // 主光源绕 y 轴，即左右旋转的角度。[ default: 40 ]
              },
              ambient: {
                // 全局的环境光设置。
                color: "#fff", // 环境光的颜色。[ default: #fff ]
                intensity: 1, // 环境光的强度。[ default: 0.2 ]
              },
            },
            postEffect: {
              bloom: {
                enable: true,
                bloomIntensity: 1,
              },
            },
            viewControl: {
              //   // 用于鼠标的旋转，缩放等视角控制。
              //   projection: 'perspective', // 投影方式，默认为透视投影'perspective'，也支持设置为正交投影'orthographic'。
              //   autoRotate: false, // 是否开启视角绕物体的自动旋转查看。[ default: false ]
              //   autoRotateDirection: 'cw', // 物体自传的方向。默认是 'cw' 也就是从上往下看是顺时针方向，也可以取 'ccw'，既从上往下看为逆时针方向。
              //   autoRotateSpeed: 10, // 物体自传的速度。单位为角度 / 秒，默认为10 ，也就是36秒转一圈。
              //   autoRotateAfterStill: 3, // 在鼠标静止操作后恢复自动旋转的时间间隔。在开启 autoRotate 后有效。[ default: 3 ]
              //   damping: 0, // 鼠标进行旋转，缩放等操作时的迟滞因子，在大于等于 1 的时候鼠标在停止操作后，视角仍会因为一定的惯性继续运动（旋转和缩放）。[ default: 0.8 ]
              //   rotateSensitivity: 1, // 旋转操作的灵敏度，值越大越灵敏。支持使用数组分别设置横向和纵向的旋转灵敏度。默认为1, 设置为0后无法旋转。	rotateSensitivity: [1, 0]——只能横旋转； rotateSensitivity: [0, 1]——只能纵向旋转。
              //   zoomSensitivity: 1, // 缩放操作的灵敏度，值越大越灵敏。默认为1,设置为0后无法缩放。
              //   panSensitivity: 1, // 平移操作的灵敏度，值越大越灵敏。默认为1,设置为0后无法平移。支持使用数组分别设置横向和纵向的平移灵敏度
              //   panMouseButton: 'left', // 平移操作使用的鼠标按键，支持：'left' 鼠标左键（默认）;'middle' 鼠标中键 ;'right' 鼠标右键(注意：如果设置为鼠标右键则会阻止默认的右键单。)
              //   rotateMouseButton: 'left', // 旋转操作使用的鼠标按键，支持：'left' 鼠标左键;'middle' 鼠标中键（默认）;'right' 鼠标右键(注意：如果设置为鼠标右键则会阻止默认的右键单。)
              distance: this.isCity ? 220 : 120, // [ default: 100 ] 默认视角距离主体的距离，对于 grid3D 和 geo3D 等其它组件来说是距离中心原点的距离,对于 globe 来说是距离地球表面的距离。在projection 为'perspective'的时候有效。
              minDistance: 60, // [ default: 40 ] 视角通过鼠标控制能拉近到主体的最小距离。在 projection 为'perspective'的时候有效。
              maxDistance: 280, // [ default: 400 ] 视角通过鼠标控制能拉远到主体的最大距离。在 projection 为'perspective'的时候有效。
              alpha: 90, // 视角绕 x 轴，即上下旋转的角度。配合 beta 可以控制视角的方向。[ default: 40 ]
              beta: 10, // 视角绕 y 轴，即左右旋转的角度。[ default: 0 ]
              // //   minAlpha: 25, // 上下旋转的最小 alpha 值。即视角能旋转到达最上面的角度。[ default: 5 ]
              // //   maxAlpha: 360, // 上下旋转的最大 alpha 值。即视角能旋转到达最下面的角度。[ default: 90 ]
              // //   minBeta: -360, // 左右旋转的最小 beta 值。即视角能旋转到达最左的角度。[ default: -80 ]
              // //   maxBeta: 360, // 左右旋转的最大 beta 值。即视角能旋转到达最右的角度。[ default: 80 ]
              // center: [-30, 60, 0], // 视角中心点，旋转也会围绕这个中心点旋转，默认为[0,0,0]。
              //   animation: true, // 是否开启动画。[ default: true ]
              //   animationDurationUpdate: 1000, // 过渡动画的时长。[ default: 1000 ]
              //   animationEasingUpdate: 'cubicInOut', // 过渡动画的缓动效果。[ default: cubicInOut ]
            },
            // itemStyle: {
            //   color: "transparent",
            //   shadowColor: 'rgba(22, 255, 255, 0.5)',
            //   shadowOffsetX:10,
            //   shadowOffsetY:10,
            //   shadowBlur: 10,
            // },
          },
          {
            name: "name1",
            type: "scatter3D",
            zlevel: -8,
            coordinateSystem: "geo3D",
            symbol: "circle",
            symbolSize: [30, 26],
            silent: false,
            data: this.plotData1,
            itemStyle: {
              color: "#44f3fb",
            },
            label: {
              show: false,
            },
            emphasis: {
              label: {
                show: false,
                color: "#fff",
              },
              itemStyle: {
                color: "#00ffc0",
              },
            },
          },
          {
            name: "name2",
            type: "scatter3D",
            zlevel: -8,
            coordinateSystem: "geo3D",
            symbol: "circle",
            symbolSize: 30,
            silent: false,
            data: this.plotData2,
            tooltip: {
              show: true,
              trigger: "item",
              itemStyle: {
                color: "#fff",
              },
              formatter: function (params) {
                return `<div class="title" style="font-size: 25px;color:#fff; line-height: 25px;font-size: 18px;">${params.name}</div>`;
              },
            },
            itemStyle: {
              color: "#e7954d",
            },
            emphasis: {
              label: {
                show: false,
                color: "#fff",
              },
              itemStyle: {
                color: "#00ffc0",
              },
            },
          },
        ],
      };

      this.myChart = this.$echarts.init(document.getElementById("mapEchart"));
      // 获取地图数据
      // 阿里生成的 china.json 数据无法显示省市文字
      // this.$echarts.registerMap("china", geoJson);

      // geo3D 和 series 配置选择其一进行配置
      const [mapName, mapJson] = getMap(this.cityMapName);
      this.$echarts.registerMap("china", mapJson);

      this.myChart.hideLoading();
      this.myChart.setOption(option);

      // this.myChart.getZr().on("click", (dom) => {
      this.myChart.on("click", (dom) => {
        console.log("dom==", dom);

        // 阻止散点图点击事件
        if (dom.seriesType === "scatter") return;
        // 暴露点击事件
        const { name: cityname, data } = dom;

        const name = cityname ? cityname : Object.keys(this.lastCity)[0];
        let code = "";
        if (dom.componentType === "series") {
          code = data?.areaUniCode ? data?.areaUniCode : this.lastCity[name];
        } else {
          code = this.lastCity[name];
        }
        const [mapName, mapJson] = getMap(dom.name);
        if (mapJson) {
          // 是否暴露点击事件
          if (dom.componentType === "series") {
            this.citylist.push({ [name]: code });
          }
          this.mapClick(code, name);
        }
        if (!mapJson) return;

        // 渲染省份、地市的 map
        option.geo3D.map = mapName;
        option.series.map = mapName;

        // 设置为undefined，可以保证地图切换时总是居中
        option.geo3D.center = undefined;
        this.$echarts.registerMap(mapName, mapJson);
        this.myChart.setOption(option);
      });
      // this.$refs["charts"].oncontextmenu = () => false;
    },

    // 向父组件提供点击事件，并提供点击省份的code和name
    mapClick(code, name) {
      console.log("code==", code, name);
      this.$emit("mapClick", { code, name });
    },
    // // 指定高亮区域
    mapActive(name) {
      console.log("province==", name);
      this.myChart &&
        this.myChart.dispatchAction({
          type: "select",
          // geo 中名称
          name,
        });
    },
  },
};
</script>

<style lang="scss" scoped>
.map {
  display: flex;
  justify-content: center;
  width: 100%;
  height: 100vh;
  .map-container {
    width: 100%;
    height: 100%;
    background: #fff;
    position: relative;
    .map-container-title {
      margin: 56px 0 16px;
      font-size: 24px;
      font-weight: 700;
      color: #333;
      line-height: 30px;
      display: flex;
      justify-content: center;
    }

    .map-chart {
      position: absolute;
      top: 0;
      left: 0;
      z-index: 5;
      height: 100%;
      width: 100%;
    }
  }
}
</style>
